package com.sy.simpleegg.serialport.util;

import java.io.ByteArrayInputStream;

/**
 * Created by kaka on 2017/4/28.
 */

public class ConvertHex {

    /**
     * 十六进制转字符串
     *
     * @param hexString
     *            十六进制字符串
     * @param encodeType
     *            编码类型4：Unicode，2：普通编码
     * @return 字符串
     */
    public static String hexStringToString(String hexString, int encodeType) {
        String result = "";
        int max = hexString.length() / encodeType;
        for (int i = 0; i < max; i++) {
            char c = (char)hexStringToAlgorism(hexString
                    .substring(i * encodeType, (i + 1) * encodeType));
            result += c;
        }
        return result;
    }
    /**
     * 十六进制字符串装十进制
     *
     * @param hex
     *            十六进制字符串
     * @return 十进制数值
     */
    public static int hexStringToAlgorism(String hex) {
        hex = hex.toUpperCase();
        int max = hex.length();
        int result = 0;
        for (int i = max; i > 0; i--) {
            char c = hex.charAt(i - 1);
            int algorism = 0;
            if (c >= '0' && c <= '9') {
                algorism = c - '0';
            } else {
                algorism = c - 55;
            }
            result += Math.pow(16, max - i) * algorism;
        }
        return result;
    }

    /**
     * 字节数组转换为十六进制字符串
     *
     * @param b
     *            byte[] 需要转换的字节数组
     * @return String 十六进制字符串
     */
    public static String byte2hex(byte b[]) {
        if (b == null) {
            throw new IllegalArgumentException(
                    "Argument b ( byte array ) is null! ");
        }
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0xff);
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs.toUpperCase();
    }

    /**
     * 字节数组转为普通字符串（ASCII对应的字符）
     *
     * @param bytearray
     *            byte[]
     * @return String
     */
    public static String bytetoString(byte[] bytearray) {
        String result = "";
        char temp;

        int length = bytearray.length;
        for (int i = 0; i < length; i++) {
            temp = (char) bytearray[i];
            result += temp;
        }
        return result;
    }

    private final static byte[] hex = "0123456789ABCDEF".getBytes();

    public static String Bytes2HexString(byte[] b) {
        byte[] buff = new byte[2 * b.length];
        for (int i = 0; i < b.length; i++) {
            buff[2 * i] = hex[(b[i] >> 4) & 0x0f];
            buff[2 * i + 1] = hex[b[i] & 0x0f];
        }
        return new String(buff);
    }

    private static final char[] HEX_CHAR = new char[]{'0', '1', '2', '3',
            '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    public static final String dumpBytes(byte[] buffer) {
        if (buffer == null) {
            return "";
        }

        StringBuffer sb = new StringBuffer();

        int count = 0;
        for (byte b : buffer) {
            sb.append((HEX_CHAR[(b & 0x00F0) >> 4])).append(
                    (HEX_CHAR[b & 0x000F]));
            count++;
            if (count % 16 == 0) {
                sb.append("\n");
            } else if (count % 4 == 0) {
                sb.append(" ");
            }
        }

        return sb.toString();
    }


    public static int byteToInt(byte b) {
        //Java 总是把 byte 当做有符处理；我们可以通过将其和 0xFF 进行二进制与得到它的无符值
        return b & 0xFF;
    }

    //byte 与 int 的相互转换
    public static byte intToByte(int x) {
        return (byte) x;
    }



    /**
     * 将16位的short转换成byte数组
     *
     * @param s
     *            short
     * @return byte[] 长度为2
     * */
    public static byte[] shortToByteArray(short s) {
        byte[] targets = new byte[2];
        for (int i = 0; i < 2; i++) {
            int offset = (targets.length - 1 - i) * 8;
            targets[i] = (byte) ((s >>> offset) & 0xff);
        }
        return targets;
    }

    /**
     * @方法功能 字节数组和长整型的转换
     * @return 长整型
     */
    public static byte[] longToByte(long number) {
        long temp = number;
        byte[] b = new byte[8];
        for (int i = 0; i < b.length; i++) {
            b[i] = new Long(temp & 0xff).byteValue();
            // 将最低位保存在最低位
            temp = temp >> 8;
            // 向右移8位
        }
        return b;
    }
    
    
    
    public static byte[] long2Bytes(long num) {  
        byte[] byteNum = new byte[8];  
        for (int ix = 0; ix < 8; ++ix) {  
            int offset = 64 - (ix + 1) * 8;  
            byteNum[ix] = (byte) ((num >> offset) & 0xff);  
        }  
        return byteNum;  
    }  
      
    public static long bytes2Long(byte[] byteNum) {  
        long num = 0;  
        for (int ix = 0; ix < 8; ++ix) {  
            num <<= 8;  
            num |= (byteNum[ix] & 0xff);  
        }  
        return num;
    }

    /**32位int转byte[]*/
    public static byte[] int2byte(int res) {
        byte[] targets = new byte[4];
        targets[0] = (byte) (res & 0xff);// 最低位
        targets[1] = (byte) ((res >> 8) & 0xff);// 次低位
        targets[2] = (byte) ((res >> 16) & 0xff);// 次高位
        targets[3] = (byte) (res >>> 24);// 最高位,无符号右移。
        return targets;
    }
    
    /* 4位字节数组转换为整型
    * @param b
    * @return
    */
   public static int byte2Int(byte[] b) {
       int intValue = 0;
       for (int i = 0; i < b.length; i++) {
           intValue += (b[i] & 0xFF) << (8 * (3 - i));
       }
       return intValue;
   }
   
   public static byte[] intToByteArray1(int i) {   
	   byte[] result = new byte[4];   
	   result[0] = (byte)((i >> 24) & 0xFF);
	   result[1] = (byte)((i >> 16) & 0xFF);
	   result[2] = (byte)((i >> 8) & 0xFF); 
	   result[3] = (byte)(i & 0xFF);
	   return result;
	 }

   public static int byte2int(byte[] res) {   
	// 一个byte数据左移24位变成0x??000000，再右移8位变成0x00??0000   
	  
	int targets = (res[0] & 0xff) | ((res[1] << 8) & 0xff00) // | 表示安位或   
	| ((res[2] << 24) >>> 8) | (res[3] << 24);   
	return targets;   
	}

    /**
     * 将byte转换为一个长度为8的byte数组，数组每个值代表bit
     */
    public static byte[] getBitArray(byte b) {
        byte[] array = new byte[8];
        for (int i = 7; i >= 0; i--) {
            array[i] = (byte)(b & 1);
            b = (byte) (b >> 1);
        }
        return array;
    }
    /**
     * 把byte转为字符串的bit
     */
    public static String byteToBit(byte b) {
        return ""
                + (byte) ((b >> 7) & 0x1) + (byte) ((b >> 6) & 0x1)
                + (byte) ((b >> 5) & 0x1) + (byte) ((b >> 4) & 0x1)
                + (byte) ((b >> 3) & 0x1) + (byte) ((b >> 2) & 0x1)
                + (byte) ((b >> 1) & 0x1) + (byte) ((b >> 0) & 0x1);
    }
   
   //字节累加总和
   public static int addByte(byte[] bytes)
   {
   	   ByteArrayInputStream byInput = new ByteArrayInputStream(bytes);
       int rs = 0;
       for(int i = 0; i < bytes.length; i++)
       {
           rs += byInput.read();
       }
       return rs;
   }
   
   //String 转8个字节，不够补0
   public static byte[] get8BytesByString(String str)
   {
	   byte[] addbyte = {0,0,0,0,0,0,0,0};
	   byte[] rsbytes = new byte[8];
	   byte[] bytes = str.getBytes();
	   int len = bytes.length;
	   for(int i = 0; i < rsbytes.length; i++)
	   {
		   if(i < bytes.length)
		   {
			   rsbytes[i] = bytes[i];
		   }
		   else
		   {
			   rsbytes[i] = addbyte[i];
		   }
	   }	   
	   return rsbytes;
   }
   
   //String 转12个字节，不够补0
   public static byte[] get12BytesByString(String str)
   {
	   byte[] addbyte = {0,0,0,0,0,0,0,0,0,0,0,0};
	   byte[] rsbytes = new byte[12];
	   byte[] bytes = str.getBytes();
	   int len = bytes.length;
	   for(int i = 0; i < rsbytes.length; i++)
	   {
		   if(i < bytes.length)
		   {
			   rsbytes[i] = bytes[i];
		   }
		   else
		   {
			   rsbytes[i] = addbyte[i];
		   }
	   }	   
	   return rsbytes;
   }
   
   /**
    * 字符串转字节组, bytesLen：字节组长度，不够补0
    * */
   public static byte[] getBytesByString(String str,int bytesLen)
   {
	   byte[] rsbytes = new byte[bytesLen];
	   byte[] bytes = str.getBytes();
	   int len = bytes.length;
	   for(int i = 0; i < rsbytes.length; i++)
	   {
		   if(i < bytes.length)
		   {
			   rsbytes[i] = bytes[i];
		   }
	   }	   
	   return rsbytes;
   }
   
   /**
    * 字节组如果<指定字节组数，则填充为0
    * */
   public static byte[] setBytesByLen(byte[] bytes,int len)
   {
	   byte[] rsbytes = new byte[len];
	   for(int i = 0; i < rsbytes.length; i++)
	   {
		   if(i < bytes.length)
		   {
			   rsbytes[i] = bytes[i];
		   }
	   }	   
	   return rsbytes;
   }
   
   /**
    * 判断当前字节组（加密部分第三个字节到最后）是否为8的倍数
    * */
   public static byte[] setdesbytes(byte[] bytes)
   {
	   //判断加密字节组是否为8的整倍数，不够补0
	   byte[] newbytes = bytes;
	   int deslen = bytes.length-2;//desbytes.length;
	   int bei = 8;
	   int tempb = deslen % bei;
	   if(tempb > 0)
	   {
	//	   int tempc = len / bei;
		   int newLen = bytes.length + (bei - tempb);
		   newbytes = new byte[newLen];
		   for(int i = 0; i < newbytes.length; i++)
		   {
			   if(i < bytes.length)
			   {
				   if(i == 1)
				   {
					   //修改长度为补0后的字节组长度
					   newbytes[i] = ConvertHex.intToByte(newbytes.length);
					   System.out.print("newbytes长度：" + newbytes.length);
				   }
				   else
				   {
					   newbytes[i] = bytes[i];
				   }
			   }
		   }
	   }
	   return newbytes;
   }

    public static byte[] intToBytes(int val)
    {
        byte[] byteArray = new byte[2];

        byteArray[0] = (byte)(val & 0xFF);	//具体跟字节序有关，可能需要调换位置
        byteArray[1] = (byte)((val >> 8) & 0xFF);

        return byteArray;
    }

    /**
     * 获取字节组里全部字节数据,返回字符串
     * */
    public static String getStrByBytes(byte[] bytes)
    {
        String showBytes = "";
        for(int i = 0; i < bytes.length; i++)
        {
            showBytes += bytes[i] + " ";
        }
        return showBytes;
    }
}
